package lee.vioson.ebook.viewmodels

import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
import androidx.navigation.NavHostController
import com.laiyifen.commonutils.StringUtils
import kotlinx.coroutines.flow.StateFlow
import lee.vioson.composecommon.base.mvi.BaseViewModel
import lee.vioson.composecommon.base.mvi.Reducer
import lee.vioson.composecommon.base.mvi.UiEvent
import lee.vioson.composecommon.base.mvi.UiState
import lee.vioson.composecommon.isNotEmpty
import lee.vioson.ebook.R
import lee.vioson.ebook.data.AppContainer
import lee.vioson.ebook.ui.AppDestinations
import lee.vioson.ebook.ui.navigate

/**
 *Author:viosonlee
 *Date:2023/6/9
 *DESCRIPTION:
 */
class RegisterViewModel(
    private val appContainer: AppContainer
) : AppViewModel<RegisterViewModel.State, RegisterViewModel.Event>(appContainer.appEvent) {

    companion object {
        fun factory(appContainer: AppContainer) = viewModelFactory {
            initializer {
                RegisterViewModel(appContainer)
            }
        }
    }

    private val reducer = SubReducer(State())

    override val state: StateFlow<State>
        get() = reducer.state

    override fun sendEvent(event: Event) {
        reducer.sendEvent(event)
    }

    /**
     * press "signup" button
     */
    fun nextStep(email: String, password: String, navHostController: NavHostController) {
        if (StringUtils.isEmail(email)) {
            sendEvent(Event.OnEmailError(""))
            navHostController.navigate(
                AppDestinations.OTP_VERIFICATION_ROUTE,
                mapOf(
                    "email" to email,
                    "password" to password,
                    "type" to "0"
                )
            )
        } else {
            sendEvent(Event.OnEmailError(appContainer.stringResource(R.string.incorrect_format)))
        }
    }


    private class SubReducer(initialState: State) :
        Reducer<State, Event>(initialState) {
        override fun reduce(oldState: State, event: Event) {
            when (event) {
                is Event.OnEmailError -> setState(oldState.copy(emailError = event.emailError))
                is Event.OnEmailChange -> {
                    val enable = oldState.password.isNotEmpty && event.email.isNotEmpty
                    setState(oldState.copy(email = event.email, enable = enable))
                }

                is Event.OnPwdChange -> {
                    val enable = oldState.email.isNotEmpty && event.password.isNotEmpty
                    setState(oldState.copy(password = event.password, enable = enable))
                }
            }
        }
    }


    sealed class Event : UiEvent {
        data class OnEmailError(val emailError: String) : Event()
        data class OnEmailChange(val email: String) : Event()
        data class OnPwdChange(val password: String) : Event()
    }

    data class State(
        val email: String = "",
        val password: String = "",
        val emailError: String = "",
        val passwdError: String = "",
        val enable: Boolean = false
    ) : UiState
}

